from sqlalchemy import Column, Integer, String, Boolean, DateTime, Text, ForeignKey, JSON, Enum
from sqlalchemy.orm import relationship
from sqlalchemy.sql import func
from app.core.database import Base
import enum

class ReleaseStatus(enum.Enum):
    """发布状态枚举"""
    PENDING = "pending"      # 待发布
    DEPLOYING = "deploying"  # 部署中
    SUCCESS = "success"      # 成功
    FAILED = "failed"        # 失败
    ROLLBACK = "rollback"    # 回滚

class ReleaseType(enum.Enum):
    """发布类型枚举"""
    MAJOR = "major"      # 主版本
    MINOR = "minor"      # 次版本
    PATCH = "patch"      # 补丁版本
    HOTFIX = "hotfix"    # 热修复

class Environment(enum.Enum):
    """环境枚举"""
    DEVELOPMENT = "development"  # 开发环境
    TESTING = "testing"         # 测试环境
    STAGING = "staging"         # 预发布环境
    PRODUCTION = "production"   # 生产环境

class Release(Base):
    """版本发布模型"""
    __tablename__ = "releases"
    
    id = Column(Integer, primary_key=True, index=True)
    version = Column(String(50), unique=True, index=True, nullable=False, comment="版本号")
    title = Column(String(200), nullable=False, comment="发布标题")
    description = Column(Text, nullable=True, comment="发布描述")
    
    # 发布信息
    release_type = Column(Enum(ReleaseType), nullable=False, comment="发布类型")
    environment = Column(Enum(Environment), nullable=False, comment="目标环境")
    status = Column(Enum(ReleaseStatus), default=ReleaseStatus.PENDING, comment="发布状态")
    
    # 代码信息
    branch = Column(String(100), nullable=False, comment="分支名称")
    commit_hash = Column(String(100), nullable=False, comment="提交哈希")
    repository_url = Column(String(500), nullable=True, comment="仓库地址")
    
    # 发布配置
    rollback_enabled = Column(Boolean, default=True, comment="是否支持回滚")
    auto_deploy = Column(Boolean, default=False, comment="是否自动部署")
    canary_percentage = Column(Integer, default=0, comment="灰度发布比例")
    
    # 时间信息
    scheduled_at = Column(DateTime(timezone=True), nullable=True, comment="计划发布时间")
    started_at = Column(DateTime(timezone=True), nullable=True, comment="开始时间")
    completed_at = Column(DateTime(timezone=True), nullable=True, comment="完成时间")
    
    # 发布人信息
    created_by = Column(Integer, ForeignKey("users.id"), nullable=False, comment="创建人")
    approved_by = Column(Integer, ForeignKey("users.id"), nullable=True, comment="审批人")
    
    # 元数据
    meta_data = Column(JSON, nullable=True, comment="发布元数据")
    change_log = Column(Text, nullable=True, comment="变更日志")
    
    # 时间字段
    created_at = Column(DateTime(timezone=True), server_default=func.now(), comment="创建时间")
    updated_at = Column(DateTime(timezone=True), onupdate=func.now(), comment="更新时间")
    
    # 关系
    logs = relationship("ReleaseLog", back_populates="release", cascade="all, delete-orphan")
    
    def __repr__(self):
        return f"<Release(id={self.id}, version='{self.version}', status='{self.status.value}')>"

class ReleaseLog(Base):
    """发布日志模型"""
    __tablename__ = "release_logs"
    
    id = Column(Integer, primary_key=True, index=True)
    release_id = Column(Integer, ForeignKey("releases.id"), nullable=False, comment="发布ID")
    
    # 日志信息
    level = Column(String(20), nullable=False, comment="日志级别")  # INFO, WARN, ERROR
    message = Column(Text, nullable=False, comment="日志消息")
    step = Column(String(100), nullable=True, comment="执行步骤")
    
    # 执行信息
    duration = Column(Integer, nullable=True, comment="执行时长(秒)")
    exit_code = Column(Integer, nullable=True, comment="退出码")
    
    # 元数据
    meta_data = Column(JSON, nullable=True, comment="日志元数据")
    
    # 时间字段
    created_at = Column(DateTime(timezone=True), server_default=func.now(), comment="创建时间")
    
    # 关系
    release = relationship("Release", back_populates="logs")
    
    def __repr__(self):
        return f"<ReleaseLog(id={self.id}, level='{self.level}', release_id={self.release_id})>"

class DeploymentConfig(Base):
    """部署配置模型"""
    __tablename__ = "deployment_configs"
    
    id = Column(Integer, primary_key=True, index=True)
    name = Column(String(100), unique=True, index=True, nullable=False, comment="配置名称")
    environment = Column(Enum(Environment), nullable=False, comment="环境")
    
    # 部署配置
    server_host = Column(String(200), nullable=False, comment="服务器地址")
    deploy_path = Column(String(500), nullable=False, comment="部署路径")
    backup_path = Column(String(500), nullable=True, comment="备份路径")
    
    # 执行脚本
    pre_deploy_script = Column(Text, nullable=True, comment="部署前脚本")
    deploy_script = Column(Text, nullable=False, comment="部署脚本")
    post_deploy_script = Column(Text, nullable=True, comment="部署后脚本")
    rollback_script = Column(Text, nullable=True, comment="回滚脚本")
    
    # 配置信息
    is_active = Column(Boolean, default=True, comment="是否激活")
    max_rollback_versions = Column(Integer, default=5, comment="最大回滚版本数")
    
    # 元数据
    meta_data = Column(JSON, nullable=True, comment="配置元数据")
    
    # 时间字段
    created_at = Column(DateTime(timezone=True), server_default=func.now(), comment="创建时间")
    updated_at = Column(DateTime(timezone=True), onupdate=func.now(), comment="更新时间")
    
    def __repr__(self):
        return f"<DeploymentConfig(id={self.id}, name='{self.name}', environment='{self.environment.value}')>"